썸네일: Unsplash의Paul Hanaoka
출처 : 웹 성능 최적화 기법
웹 성능 최적화 기법(루비페이퍼 사) 도서에 대한 핵심 내용과 지식을 정리한 포스트입니다. 포스트에 올라오는 내용은 도서의 일부이기 때문에 더 자세한 내용이 궁금하신 분들은 출처에서 도서를 구매해 읽어보시는 것을 추천드립니다.
6.3 캐시 최적화 방안
- 캐시 사용 최대화 3가지 기본 원리
- 최대한 많이 캐시하라
- 최대한 오래 캐시하라
- 최대한 가까이 캐시하라
6.3.1 캐시 가능한 콘텐츠 구분하기
- 어떤 콘텐츠를 캐시할 수 있는지, 캐시하면 안되는 지를 알아야하며, 캐시 가능한 리소스를 최대한 찾아내 서비스할 필요가 있다.
- WebPageTest를 통해 웹 페이지 구성이 어떻게 되고, 얼마나 많은 파일들을 캐시할 수 있는지 확인할 수 있다.
- 웹 사이트 내 콘텐츠는 정적 콘텐츠와 동적 콘텐츠로 구분할 수 있다.
- 정적 콘텐츠 : URL을 호출할 때마다 변함없이 같은 응답을 주는 콘텐츠로 이미지, CSS, 자바스크립트 등
- 동적 콘텐츠 : 사용자 요청시마다 서버에 의해 다시 생성, 응답되는 콘텐츠로 서버에서는 HTTP 요청과 함께 입력 시간을 포함한 다양한 변숫값에 따라 콘텐츠를 동적으로 생성하여 응답
- 캐시하기 어려운 콘텐츠
- 개인화된 콘텐츠
- API 호출이나 Ajax 요청에 대한 콘텐츠
- Beacon 전달 또는 쿠키 설정을 위한 호출
6.3.2 올바른 캐시 정책 설정하기
1. 캐시할 수 있는 콘텐츠인지 판단하기
- 일반적으로 정적 콘텐츠들이 캐시 가능한 페이지로 분류될 수 있지만 모든 정적 콘텐츠를 캐시할 수는 없다. (보안에 민감한 내용 등)
- 캐시할 수 없는 콘텐츠의 경우 응답 헤더에 Cache-Control : no-store를 설정한다.
2. 캐시할 수 있는 콘텐츠들은 매번 원본 서버에 변경 사항을 확인해야 하는지 판단
- 정적이지만 자주 변하는 콘텐츠들의 경우 변경시 캐시에 바로 업데이트 할 필요가 있다.
- 변경에 민감한 콘텐츠를 응답 헤더에 Cache-Control: no-cache 혹은 Cache-Control: max-age=0을 설정한다.
3. 캐시할 콘텐츠 성격 판단
- 모든 사용자 공통 콘텐츠는 Cache-Control:public, 개인화된 콘텐츠는 Cache-Control:private 사용
4. 캐시 주기 설정 및 max-age 추가
6.3.3 캐시 주기 결정하기
- 캐시 주기는 가능한한 오래하는 것이 좋다. 캐시 주기가 길수록 사용자 요청이 캐시에서 처리되어 서버까지의 트래픽을 많이 감소시킬 수 있기 때문
- 캐시 주기가 짧으면 원본 파일 변경이 캐시에 빠르게 반영된다는 장점이 있다.
1. 캐시 주기는 콘텐츠 타입별로 다르게 설정 가능
- 이미지, 동영상 등 미디어 파일 등은 쉽게 변경되지 않으며, 미디어 파일은 링크가 바뀌면 자연스럽게 새로운 파일을 불러와 캐시하므로 내용 변경 필요없이 링크만 바꾸면 된다.
- 특별한 이유가 없다면 캐시 주기를 1년 정도로 길게 설정하는 것이 좋다.
2. 링크 변경 없이 이미지 내용만 바꿔야 한다면 캐시 무효화(Invalidation) 방식으로 해당 이미지만 캐시에 업데이트한다.
- 이미지, 미디어 파일을 제외한 웹 리소스 파일들은 변경 주기에 따라 다르게 설정하며 범위에서 가능한 길게 설정한다.
- 폰트 파일은 캐시 주기를 길게, 스타일 시트 등은 상대적으로 짧게 설정한다.
- 아예 캐시를 안하는 것보다는 짧게라도 캐시 주기를 정해서 캐시하는 것이 성능에 유리
3. 모든 정적 파일에 대해 캐시 주기를 길게 설정하거나 수동으로 캐시 주기를 관리할 수도 있다.
- 수동으로 캐시 주기를 관리하는 방법 2가지
- 파일명 뒤에 해시값을 자동으로 붙여 파일명을 변경하는 방법
- 파일 요청 시에 쿼리 스트링으로 버전을 지정하는 방법
6.3.4 캐시에 적합한 디렉터리 구조 구성하기
1. 캐시할 수 있는 콘텐츠를 별도의 폴더에 분류해 관리한다.
- 정적 콘텐츠들을 /static 디렉터리로 관리하는 방법 등
2. 캐시 주기별로 나누어 구성한다.
- 주기별로 디렉터리를 나누어 관리하기
3. 동일한 파일을 여러 곳에 분산시키지 않는다.
6.3.5 캐시 키 올바르게 사용하기
- 캐시 키란, 캐시 서버가 원본의 복사본을 저장하고 빠르게 조회하기 위해 사용하는 키 값을 말한다.
일반적인 캐시 키 구성
호스트/패스? 쿼리 스트링
www.foekorea.com/kr/feo/optimization/myPic.jpg?width=200&height=100
캐시 키들은 서로 다른 객체를 참조한다
www.foekorea.com/kr/feo/optimization/myPic.jpg
www.foekorea.com/jp/feo/optimization/myPic.jpg
www.foekorea.com/jp/feo/optimization/myPic.jpg?width=200
캐시 오염과 캐시 충돌
- 캐시 오염: 원본 서버에 하나의 원본 파일만 존재하는데 캐시에 복사본이 여러 개 존재하는 것
- 캐시 충돌 : 요청 URL이 하나인데 브라우저 환경에 따라 서버에서 제공하는 응답이 달라져 최초 요청한 브라우저의 응답만 캐시되는 것
캐시 오염 제거
- 캐시 오염은 최종 사용자에게 영향을 주지는 않지만 캐시 서버의 효율성에 큰 영향을 미칠 수 있으며, 캐시가 퍼지면 트래픽 부담을 줄 수 있다.
- URL에 특정 쿼리 스트링 값이 달라지더라도 응답이 항상 같다면 캐시 키에서 쿼리 스트링 무시하도록 설정
- 쿼리 스트링 순서를 동일하게 정렬
- Vary 헤더 사용
캐시 충돌 방지
- 동적 페이지를 캐시할 때 주로 발생하며, 일반적인 홈페이지는 로그인 전후로 같은 URL을 사용하기 때문에 동적 페이지에 대한 특별한 캐시 설정을 하지 않으면 캐시 충돌 현상이 나타난다.
- 캐시 충돌을 피하려면 기본적으로 동적 페이지에는 캐시를 적용하지 않아야 하며, 일부 동적 페이지에 캐시를 사용하고자 한다면 Cache-Control:private로 브라우저에만 캐시하여 페이지 로딩 시간을 단축할 수 있다.
6.3.6 CDN 사용하기
- 캐시 효율화를 위한 3원칙 중 사용자에게 가깝게 캐시하라는 내용에 해당
- 글로벌 서비스를 운용중이라면, CDN을 사용하여 세계 여러 지역 데이터 센터들에 리버스 프록시 캐시 서버를 두고 필요한 정적 콘텐츠들을 저장해놓을 수 있다.
6.4 동적 콘텐츠 캐시
- 특성에 따른 웹 콘텐츠 분류
1. 정적 콘텐츠와 동적 콘텐츠
- 정적 콘텐츠
- 한번 생성되어 좀처럼 변하지 않는 콘텐츠
- 이미지, 동영상, CSS, 자바스크립트 등
- 동적 콘텐츠
- 사용자 요청에 따라 서버가 바로 생성하는 콘텐츠
- 장바구니, 주식 시세,
- JSON, XML, HTML 형태 데이터
2. 익명(anonymous) 콘텐츠와 개인화(personalized) 콘텐츠
- 익명 콘텐츠 : 누구에게나 드러나는 콘텐츠
- 개인화 콘텐츠 : 사용자 정보에 따라 다르게 나타나는 콘텐츠
3. 시간에 민감한 콘텐츠와 시간에 둔감한 콘텐츠
6.4.1 동적 콘텐츠 캐시
- 원본 서버가 동적 콘텐츠를 사용자에게 전달하는 방법
- 동적 정보를 쿠키에 넣어 보낸다.
- Ajax 요청으로 관련 정보를 동적으로 받아온다.
- 요청 쿠키, 헤더 혹은 쿼리 스트링에 동적 콘텐츠에 대한 정보가 있으면, 이 정보들을 캐시 키에 추가하여 동적 콘텐츠를 캐시할 수 있다.
주의점
- 보안에 주의해야 한다.
- 개인화 콘텐츠에는 사생활을 침해하는 개인 정보가 포함되어 있을 수 있다.
- 캐시 서버 용량에 유의해야 한다.
- 캐시 서버 용량이 소진되면 CPU 사용량이 늘어나 캐시 효율이 떨어지므로 과도한 개인 콘텐츠 캐시는 지양한다.
6.4.2 POST 응답 캐시
- POST 메서드는 HTTP 페이로드 메시지에 쿼리 스트링을 포함시켜 보낼 때 사용한다
- GET메소드는 쿼리 스트링 길이에 제한이 있지만, POST 메서드는 HTTP 헤더에 쿼리 스트링 내용을 포함해 보내므로 데이터 크기에 제한이 없으며, 보안 측면에서도 상대적으로 안전하다.
- POST 메서드의 응답 내용이 안전한 내용이라면 캐시할 수 있으며, 이때 MD5 같은 해시 알고리즘을 이용해 암호화해야 한다.
6.5 고급 캐시 전략
6.5.1 Edge Side Include
- 웹 페이지의 첫 번째 HTML이 서버에서 브라우저까지 도달하는 시간을 Time To First Byte라고 하며, 웹 사이트를 측정하는 중요 지표가 된다.
- 그러나 많은 웹 관리자들은 동적인 콘텐츠가 존재하기 때문에 첫 번째 HTML을 캐시하지 않는데, 동적 부분만 따로 떼어 별도로 수행시킨 후 캐시된 나머지와 다시 조합하면 로딩 성능이 개선될 수 있다.
- 특히 CDN 에지 서버에 캐시되어 있으면 개선 폭이 더 커진다.
ESI
- ESI는 인터넷 에지에서 웹 페이지 조각을 동적으로 조합, 조립, 전달할 수 있도록 이에 대한 문법과 용도를 정의한 XML 기반 표준 마크업 언어이다.
- ESI를 사용하면 한 페이지 안에 다른 페이지를 포함시킬 수 있으며, 각 페이지들이 독립 객체로 취급되어 각 다른 캐시 정책을 사용할 수 있다.
- ESI는 HTML 같은 마크업 언어이며 문법이 단순해 쉽게 배우고 빠르게 사용할 수 있다.
- ESI 언어를 지원하는 대표적인 오픈 소스 웹 캐시는 Varnish, Squid 등이 있고, Oracle, IBM 등 중요 기업형 소프트웨어 업체에서 판매하는 상용 웹 캐시도 ESI를 지원한다.
ESI 사용 용도
- 페이지 내에 일부 동적인 부분이 존재할 때, 이 부분만 별도로 만들어 본래 페이지에 동적으로 삽입
- 서로 다른 성격 콘텐츠를 각 캐시 정책을 사용해 캐시하고자 할 때
- 사용자 등급에 따라 콘텐츠를 제한하고자 할 때
- 웹 애플리케이션 개발에 협업이 필요할 때
6.5.2 HTML5 로컬 스토리지
- HTML5는 Web Hypertext Application Technology Working Group(WHATWG)에서 작업한 표준으로 2014년 W3C를 통해 발표됨
- HTML5의 가장 큰 장점 중 하나는 HTML5만의 다양한 기능을 API를 사용할 수 있도록 되어 웹 페이지 자체가 일종의 웹/모바일 어플리케이션으로 구동될 수 있게된 점이다.
HTML5 주요 기능
- WeSemantic Tag: Semantic을 표준 Tag로 정의해 사용하여 머신 간 가독성 및 사용자 접근성 향상
- Web Storage : API를 통해 세션 스토리지, 로컬 스토리지 IndexedDB 사용가능하며, 오프라인 상태에서 웹페이지 로딩 가능
- Multimedia : 플러그인 없이 오디오와 비디오 재생 가능
- Graphics : SVG, Canvas, WebGL, CSS 3D 등 확대외어 플러그인 없이 화려한 그래픽 표현
- Device Access : 기기의 마이크로폰, 카메라, 연락처, 이벤트 등에 네이티브 앱처럼 접근 가능
- Performance : Web Worker를 도입해 백그라운드 프로세싱 기능과 멀티스레드 사용하여 속도 향상
- Connectivity : Web Socket을 사용해 클라이언트 서버 간 TCP 통신 가능 (실시간 메시징, 푸시 알림 구현)
- CSS3 지원
웹 스토리지
- 사용자 주요 정보, 웹 리소스들을 브라우저 로컬 저장소에 저장하여 재사용이 가능
- 최소 5MB 크기
- 쿠키를 대체하여 네트워크 대역폭 낭비를 절약하는 용도로 사용
- 세션이 살아있을 동안만 저장되는 세션 스토리지, 영원히 저장되는 로컬 스토리지로 구분